home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / System / Swatch / Development / swatch 1.7 / heap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-09  |  15.5 KB  |  684 lines  |  [TEXT/KAHL]

  1. /**
  2.  
  3.     heap.c
  4.     Copyright (c) 1990-1992, joe holt
  5.  
  6.  **/
  7.  
  8.  
  9. /**-----------------------------------------------------------------------------
  10.  **
  11.  **    Headers
  12.  **
  13.  **/
  14.  
  15. #ifndef __ctypes__
  16. #include "ctypes.h"
  17. #endif
  18. #ifndef __heap__
  19. #include "heap.h"
  20. #endif
  21. #ifndef __info__
  22. #include "info.h"
  23. #endif
  24. #ifndef __prefs__
  25. #include "prefs.h"
  26. #endif
  27. #ifndef __swatch__
  28. #include "swatch.h"
  29. #endif
  30.  
  31.  
  32. /**-----------------------------------------------------------------------------
  33.  **
  34.  ** Private Constants
  35.  **
  36.  **/
  37.  
  38. #define BLOCK_TYPE_MASK                    0xC0
  39. #define BLOCK_FREE                        0x00
  40. #define BLOCK_NON_RELOCATABLE            0x40
  41. #define BLOCK_RELOCATABLE                0x80
  42.  
  43. #define MASTER_POINTER_LOCK_MASK        0x80
  44. #define MASTER_POINTER_PURGE_MASK        0x40
  45. #define MASTER_POINTER_RESOURCE_MASK    0x20
  46.  
  47.  
  48. /**-----------------------------------------------------------------------------
  49.  **
  50.  ** Private Variables
  51.  **
  52.  **/
  53.  
  54. /*
  55.  
  56.     A 32-bit block header is:
  57.  
  58.     1 byte block type ($40 = non-relo, etc)
  59.     1 byte block flags ($80 = locked, etc)
  60.     2 bytes alignment
  61.     1 long size of block
  62.     1 long relative handle, etc
  63.  
  64.     The physical size of the block is in the second long word. To get to the next block
  65.     header, just add the size of the block.
  66.  
  67. */
  68.  
  69. typedef struct {
  70.     unsigned char type;
  71.     unsigned char flags;
  72.     int16 alignment;
  73.     int32 size;
  74.     int32 relative_handle;
  75. } header_32_t;
  76.  
  77.  
  78. /**-----------------------------------------------------------------------------
  79.  **
  80.  ** Private Functions
  81.  **
  82.  **/
  83.  
  84. static void make_24_bit_heap( Heap_info_t *d );
  85. static void make_32_bit_heap( Heap_info_t *hi );
  86. static void make_32_bit_heap_old( Heap_info_t *d );
  87.  
  88.  
  89. /*******************************************************************************
  90.  **
  91.  **    Public Functions
  92.  **
  93.  **/
  94.  
  95.  
  96. void Heap_update_current( Heap_info_handle_t h )
  97. {
  98.     Heap_info_t *hi = l_access( h );
  99.     if ( hi->heap_is_32_bit )
  100.         make_32_bit_heap( hi );
  101.     else
  102.         make_24_bit_heap( hi );
  103.     l_release( h );
  104. }
  105.  
  106.  
  107. Boolean Heap_locate_block( Heap_info_t *d, void *address, Heap_block_info_t *info )
  108. {
  109.     int32 blocks_checked;
  110.  
  111.     blocks_checked = 0;
  112.  
  113.     if ( d->heap_is_32_bit ) {
  114.         Ptr bh, bkLim;
  115.         int32 size;
  116.     
  117.         bh = (Ptr) &d->zone->heapData;
  118.         bkLim = d->zone->bkLim;
  119.  
  120.         for ( ;; ) {
  121.             ++blocks_checked;
  122.  
  123.             if ( bh > bkLim || ( (int32) bh & 1 ) )
  124.                 return false;        // heap bad
  125.  
  126.             if ( bh == bkLim )
  127.                 return false;        // block not in this heap
  128.  
  129.             size = ((header_32_t *)bh)->size;
  130.             if ( bh + size <= bh )
  131.                 return false;        // heap bad
  132.  
  133.             if ( (Ptr)address < (bh + size) && (Ptr)address >= bh ) {
  134.                 info->physical_start = bh;
  135.                 info->physical_end = bh + size - 1;
  136.                 info->logical_start = bh + 12;
  137.                 info->logical_end = info->physical_end - ((header_32_t *)bh)->alignment;
  138.                 info->type = ((header_32_t *)bh)->type & 0xC0;
  139.                 info->flags = ((header_32_t *)bh)->flags & 0xE0;
  140.                 if ( info->type & BLOCK_TYPE_RELOCATABLE_MASK )
  141.                     info->handle =
  142.                             (Handle)(((header_32_t *)bh)->relative_handle + (int32)d->zone);
  143.                 else info->handle = NULL;
  144.                 return true;
  145.             }
  146.  
  147.             bh += size;
  148.         }
  149.     }
  150.     else {
  151.         Ptr bh, bkLim;
  152.         int32 size;
  153.     
  154.         bh = (Ptr) &d->zone->heapData;
  155.         bkLim = d->zone->bkLim;
  156.  
  157.         for ( ;; ) {
  158.             ++blocks_checked;
  159.  
  160.             if ( bh > bkLim || ( (int32) bh & 1 ) )
  161.                 return false;        // heap bad
  162.  
  163.             if ( bh == bkLim )
  164.                 return false;        // block not in this heap
  165.  
  166.             size = *(int32 *) bh & 0x00FFFFFF;
  167.             if ( bh + size <= bh )
  168.                 return false;        // heap bad
  169.  
  170.             if ( (Ptr)address < (bh + size) && (Ptr)address >= bh ) {
  171.                 info->physical_start = bh;
  172.                 info->physical_end = bh + size - 1;
  173.                 info->logical_start = bh + 8;
  174.                 info->logical_end = info->physical_end - (*(unsigned char *)bh & 0x0F);
  175.                 info->type = *(unsigned char *)bh & 0xC0;
  176.                 if ( info->type & BLOCK_TYPE_RELOCATABLE_MASK                                                                                                                                                                                                                                                                                                                                                                                                                                                               ) {
  177.                     info->handle =
  178.                             (Handle)(*(int32 *)(bh + 4) + (int32)d->zone);
  179.                     info->flags = *(unsigned char *)info->handle & 0xE0;
  180.                 }
  181.                 else {
  182.                     info->handle = NULL;
  183.                     info->flags = 0;
  184.                 }
  185.                 return true;
  186.             }
  187.  
  188.             bh += size;
  189.         }
  190.     }
  191. }
  192.  
  193.  
  194. Boolean get_x_process_information( Heap_info_t *d )
  195. {
  196.     THz zone;
  197.     Ptr bh, bkLim;
  198.     int32 size;
  199.     Boolean is_32;
  200.     Heap_info_t *hi;
  201.  
  202.     if ( d->xinfo ) return true;
  203.  
  204. // first time thru -- gotta look for it
  205.  
  206.     hi = l_access( multifinder );
  207.     zone = hi->zone;
  208.     bh = (Ptr) &zone->heapData;
  209.     bkLim = zone->bkLim;
  210.     is_32 = hi->heap_is_32_bit;
  211.     l_release( multifinder );
  212.  
  213.     if ( is_32 ) {
  214.  
  215.         for ( ;; ) {
  216.  
  217.             if ( bh > bkLim || ( (int32) bh & 1 ) ) return false;  // heap bad
  218.  
  219.             if ( bh == bkLim ) return false;  // block not in this heap
  220.  
  221.             size = ((header_32_t *)bh)->size;
  222.             if ( bh + size <= bh ) return false;  // heap bad
  223.  
  224.             if ( size >= sizeof(ExtendedProcessInfoRec) &&
  225.                 ((header_32_t *)bh)->type == BLOCK_RELOCATABLE ) {
  226.                 ExtendedProcessInfoRec *p = (ExtendedProcessInfoRec *) (bh + 12);
  227.                 if ( p->processSignature == d->info.processSignature &&
  228.                      p->processType == d->info.processType ) {
  229.                     d->xinfo = (ExtendedProcessInfoRec **)
  230.                         ((int32) zone + ((header_32_t *)bh)->relative_handle);
  231.                     return true;
  232.                 }
  233.             }
  234.  
  235.             bh += size;
  236.  
  237.         }
  238.  
  239.     }
  240.     else {
  241.  
  242.         for ( ;; ) {
  243.  
  244.             if ( bh > bkLim || ( (int32) bh & 1 ) ) return false;  // heap bad
  245.  
  246.             if ( bh == bkLim ) return false;  // block not in this heap
  247.  
  248.             size = *(int32 *) bh & 0x00FFFFFF;
  249.             if ( bh + size <= bh ) return false;  // heap bad
  250.  
  251.             if ( size >= sizeof(ExtendedProcessInfoRec) &&
  252.                 (*(unsigned char *) bh & BLOCK_TYPE_MASK) == BLOCK_RELOCATABLE ) {
  253.                 ExtendedProcessInfoRec *p = (ExtendedProcessInfoRec *) (bh + 8);
  254.                 if ( p->processSignature == d->info.processSignature &&
  255.                      p->processType == d->info.processType ) {
  256.                     d->xinfo = (ExtendedProcessInfoRec **)
  257.                         ((int32) zone + (*(int32 *) (bh + 4)));
  258.                     return true;
  259.                 }
  260.             }
  261.  
  262.             bh += size;
  263.         }
  264.     }
  265.  
  266.     return false;
  267. }
  268.  
  269.  
  270. static void make_24_bit_heap( Heap_info_t *d )
  271. {
  272.     Ptr bh, tp;
  273.     THz zone;
  274.     int32 chunk_size, size;
  275.     uns16 run_type, block_type;
  276.     uns16 last_run_type;
  277.     int32 this_run;
  278.     int32 *p;
  279.     int32 i;
  280.  
  281.     zone = d->zone;
  282.     bh = (Ptr) &zone->heapData;
  283.  
  284.     d->current_heap_transitions = 1;
  285.     p = &d->current_heap[0];
  286.     run_type = last_run_type = HEAP_LOCKED_RUN;
  287.     this_run = (int32) run_type << 24;
  288.     chunk_size = 0;
  289.  
  290.     for (;;) {
  291.         if ( bh >= BufPtr || ( (int32) bh & 1 ) )
  292.             goto heap_bad;
  293.  
  294.         size = *(int32 *) bh & 0x00FFFFFF;
  295.         block_type = *(unsigned char *) bh & BLOCK_TYPE_MASK;
  296.         if ( (chunk_size += size) >= Prefs.heap_scale ) {
  297.             if ( run_type == last_run_type )
  298.                 ++this_run;
  299.             else {
  300.                 *p++ = this_run;
  301.                 if ( d->current_heap_transitions == MAX_HEAP_TRANSITIONS )
  302.                     break;
  303.                 ++d->current_heap_transitions;
  304.                 this_run = ((int32) run_type << 24) + 1;
  305.                 last_run_type = run_type;
  306.             }
  307.  
  308.             if ( !block_type )
  309.                 run_type = HEAP_FREE_RUN;
  310.             else if ( block_type == BLOCK_NON_RELOCATABLE )
  311.                 run_type = HEAP_LOCKED_RUN;
  312.             else {
  313.                 tp = (Ptr) zone + *(int32 *) (bh + 4);
  314.                 if ( tp >= BufPtr || ( (int32) tp & 1 ) )
  315.                     goto heap_bad;
  316.                 if ( *tp & MASTER_POINTER_LOCK_MASK )
  317.                     run_type = HEAP_LOCKED_RUN;
  318.                 else if ( *tp & MASTER_POINTER_PURGE_MASK )
  319.                     run_type = HEAP_PURGEABLE_RUN;
  320.                 else
  321.                     run_type = HEAP_UNLOCKED_RUN;
  322.             }
  323.             chunk_size -= Prefs.heap_scale;
  324.             if ( chunk_size >= Prefs.heap_scale ) {
  325.                 if ( run_type != last_run_type ) {
  326.                     *p++ = this_run;
  327.                     if ( d->current_heap_transitions == MAX_HEAP_TRANSITIONS )
  328.                         break;
  329.                     ++d->current_heap_transitions;
  330.                     this_run = (int32) run_type << 24;
  331.                     last_run_type = run_type;
  332.                 }
  333.                 i = chunk_size >> Prefs.heap_scale_2n;
  334.                 this_run += i;
  335.                 chunk_size -= (int32) i << Prefs.heap_scale_2n;
  336.             }
  337.         }
  338.         else if ( run_type != HEAP_LOCKED_RUN ) {
  339.             if ( !block_type )
  340.                 ;
  341.             else if ( block_type == BLOCK_NON_RELOCATABLE )
  342.                 run_type = HEAP_LOCKED_RUN;
  343.             else {
  344.                 tp = (Ptr) zone + *(int32 *) (bh + 4);
  345.                 if ( tp >= BufPtr || ( (int32) tp & 1 ) )
  346.                     goto heap_bad;
  347.                 if ( *tp & MASTER_POINTER_LOCK_MASK )
  348.                     run_type = HEAP_LOCKED_RUN;
  349.                 else if ( *tp & MASTER_POINTER_PURGE_MASK )
  350.                     run_type = HEAP_PURGEABLE_RUN;
  351.                 else
  352.                     run_type = HEAP_UNLOCKED_RUN;
  353.             }
  354.         }
  355.  
  356.         if ( bh + size <= bh )
  357.             goto heap_bad;
  358.         bh += size;
  359.  
  360.         if ( bh < zone->bkLim )
  361.             continue;
  362.  
  363.         if ( bh > zone->bkLim )
  364.             goto heap_bad;
  365.  
  366.         if ( chunk_size )
  367.             ++this_run;
  368.         *p = this_run;
  369.         break;
  370.     }
  371.  
  372.     d->current_heap_ok = TRUE;
  373.     return;
  374.  
  375. heap_bad:
  376.     d->current_heap_ok = FALSE;
  377. }
  378.  
  379.  
  380. static uns8 run_type_priority[] = {  // zero element not used
  381.     1, 1, 2, 2, 4, 4, 4, 4,
  382.     8, 8, 8, 8, 8, 8, 8, 8
  383. };
  384.  
  385.  
  386. static void make_32_bit_heap( Heap_info_t *hi )
  387. {
  388.     Ptr block;
  389.     THz zone;
  390.     int32 bytes_this_pixel, block_size;
  391.     uns16 block_type;
  392.     int32 pixels_this_run, *p;
  393.  
  394.     int32 bytes_per_pixel;
  395.     int16 bytes_per_pixel_2n;
  396.  
  397.     uns8 run_type, display_type, last_display_type, display_types_seen;
  398.  
  399.     zone = hi->zone;
  400.     block = (Ptr) &zone->heapData;
  401.  
  402.     bytes_per_pixel = Prefs.heap_scale;
  403.     bytes_per_pixel_2n = Prefs.heap_scale_2n;
  404.  
  405.     hi->current_islands = 0;
  406.  
  407.     hi->current_heap_transitions = 0;
  408.     p = &hi->current_heap[0];
  409.  
  410.     pixels_this_run = 0;
  411.     bytes_this_pixel = 0;
  412.     display_types_seen = 0;
  413.     last_display_type = HEAP_LOCKED_RUN;        // assume heap begins with locked blocks
  414.     run_type = HEAP_LOCKED_RUN;
  415.  
  416.  
  417.     while ( block < zone->bkLim ) {
  418.  
  419.  
  420. // heap okay check
  421.  
  422.         if ( block >= BufPtr || ( (int32) block & 1 ) ) goto heap_bad;
  423.  
  424.         block_size = ((header_32_t *) block)->size;
  425.  
  426.  
  427. // classify block type: free, purgeable, unlocked or locked
  428.  
  429.         block_type = ((header_32_t *) block)->type;
  430.         if ( block_type == BLOCK_FREE )
  431.             display_type = HEAP_FREE_RUN;
  432.         else if ( block_type == BLOCK_NON_RELOCATABLE )
  433.             display_type = HEAP_LOCKED_RUN;
  434.         else {
  435.             Ptr tp = (Ptr) zone + ((header_32_t *) block)->relative_handle;
  436.             if ( tp >= BufPtr || ( (int32) tp & 1 ) )
  437.                 goto heap_bad;
  438.             if ( ((header_32_t *) block)->flags & MASTER_POINTER_LOCK_MASK )
  439.                 display_type = HEAP_LOCKED_RUN;
  440.             else if ( ((header_32_t *) block)->flags & MASTER_POINTER_PURGE_MASK )
  441.                 display_type = HEAP_PURGEABLE_RUN;
  442.             else
  443.                 display_type = HEAP_UNLOCKED_RUN;
  444.         }
  445.  
  446.  
  447. // include this block's type in list of types seen for this pixel
  448.  
  449.         display_types_seen |= display_type;
  450.  
  451.  
  452. // update island count at block resolution (not pixel resolution)
  453.  
  454.         if ( display_type != last_display_type ) {
  455.             last_display_type = display_type;
  456.             if ( display_type == HEAP_LOCKED_RUN ) ++hi->current_islands;
  457.         }
  458.  
  459.  
  460.         bytes_this_pixel += block_size;
  461.         if ( bytes_this_pixel >= bytes_per_pixel ) {
  462.  
  463.             uns8 this_pixel_type = run_type_priority[display_types_seen];
  464.             bytes_this_pixel -= bytes_per_pixel;
  465.  
  466.             if ( this_pixel_type == run_type ) ++pixels_this_run;
  467.             else {
  468.  
  469.                 *p++ = ((int32)run_type << 24) | pixels_this_run;
  470.                 ++hi->current_heap_transitions;
  471.  
  472.                 if ( hi->current_heap_transitions == MAX_HEAP_TRANSITIONS )
  473.                     goto heap_too_messy;
  474.  
  475.                 run_type = this_pixel_type;
  476.                 pixels_this_run = 1;
  477.  
  478.             }
  479.  
  480.  
  481.             if ( bytes_this_pixel >= bytes_per_pixel ) {
  482.  
  483.                 uns8 addl_pixels_type = run_type_priority[display_type];
  484.                 int32 addl_pixels = bytes_this_pixel >> bytes_per_pixel_2n;
  485.                 bytes_this_pixel -= addl_pixels << bytes_per_pixel_2n;
  486.  
  487.                 if ( addl_pixels_type == run_type ) pixels_this_run += addl_pixels;
  488.                 else {
  489.  
  490.                     *p++ = ((int32)run_type << 24) | pixels_this_run;
  491.                     ++hi->current_heap_transitions;
  492.     
  493.                     if ( hi->current_heap_transitions == MAX_HEAP_TRANSITIONS )
  494.                         goto heap_too_messy;
  495.     
  496.                     run_type = addl_pixels_type;
  497.                     pixels_this_run = addl_pixels;
  498.  
  499.                 }
  500.     
  501.             }
  502.  
  503.             display_types_seen = (bytes_this_pixel) ? display_type : 0;
  504.  
  505.         }
  506.  
  507.  
  508. // skip to next block; heap okay checks
  509.  
  510.         if ( block + block_size <= block ) goto heap_bad;
  511.         block += block_size;
  512.  
  513.     }
  514.  
  515.  
  516. // at this point we've checked every block in the heap
  517.  
  518.     if ( block > zone->bkLim ) goto heap_bad;
  519.  
  520.  
  521. // include last partial pixel
  522.  
  523.     if ( bytes_this_pixel ) {
  524.  
  525.         uns8 final_pixel_type = run_type_priority[display_types_seen];
  526.  
  527.         if ( final_pixel_type == run_type ) ++pixels_this_run;
  528.         else {
  529.  
  530.             *p++ = ((int32)run_type << 24) | pixels_this_run;
  531.             ++hi->current_heap_transitions;
  532.  
  533.             if ( hi->current_heap_transitions == MAX_HEAP_TRANSITIONS )
  534.                 goto heap_too_messy;
  535.  
  536.             run_type = final_pixel_type;
  537.             pixels_this_run = 1;
  538.  
  539.         }
  540.  
  541.     }
  542.  
  543.  
  544. // include last run
  545.  
  546.     *p++ = ((int32)run_type << 24) | pixels_this_run;
  547.     ++hi->current_heap_transitions;
  548.  
  549.  
  550. // last locked block at end of heap is not an island
  551.  
  552.     if ( display_type == HEAP_LOCKED_RUN && hi->current_islands > 0 )
  553.         --hi->current_islands;
  554.  
  555.  
  556.     hi->current_heap_ok = TRUE;
  557.     return;
  558.  
  559. heap_bad:
  560.     hi->current_heap_ok = FALSE;
  561.     return;
  562.  
  563. heap_too_messy:
  564.     DebugStr( "\pHeap too messy...setting heap status to bad, but it isn't, really" );
  565.     hi->current_heap_ok = FALSE;    
  566. }
  567.  
  568.  
  569. #if 0
  570. static void make_32_bit_heap_old( Heap_info_t *d )
  571. {
  572.     Ptr tp, bh;
  573.     THz zone;
  574.     int32 chunk_size, size;
  575.     uns16 run_type, block_type;
  576.     uns16 last_run_type;
  577.     int32 this_run;
  578.     int32 *p;
  579.     int32 i;
  580.     int32 heap_scale;
  581.     int16 heap_scale_2n;
  582.  
  583.     zone = d->zone;
  584.     bh = (Ptr) &zone->heapData;
  585.  
  586.     d->current_heap_transitions = 1;
  587.     p = &d->current_heap[0];
  588.     run_type = last_run_type = HEAP_LOCKED_RUN;
  589.     this_run = (int32) run_type << 24;
  590.     chunk_size = 0;
  591.  
  592.     heap_scale = Prefs.heap_scale;
  593.     heap_scale_2n = Prefs.heap_scale_2n;
  594.  
  595.     for (;;) {
  596.         if ( bh >= BufPtr || ( (int32) bh & 1 ) )
  597.             goto heap_bad;
  598.  
  599.         size = ((header_32_t *) bh)->size;
  600.         block_type = ((header_32_t *) bh)->type;
  601.  
  602.         if ( (chunk_size += size) >= heap_scale ) {
  603.             if ( run_type == last_run_type )
  604.                 ++this_run;
  605.             else {
  606.                 *p++ = this_run;
  607.                 if ( d->current_heap_transitions == MAX_HEAP_TRANSITIONS )
  608.                     break;
  609.                 ++d->current_heap_transitions;
  610.                 this_run = ((int32) run_type << 24) + 1;
  611.                 last_run_type = run_type;
  612.             }
  613.  
  614.             if ( block_type == BLOCK_FREE )
  615.                 run_type = HEAP_FREE_RUN;
  616.             else if ( block_type == BLOCK_NON_RELOCATABLE )
  617.                 run_type = HEAP_LOCKED_RUN;
  618.             else {
  619.                 tp = (Ptr) zone + ((header_32_t *) bh)->relative_handle;
  620.                 if ( tp >= BufPtr || ( (int32) tp & 1 ) )
  621.                     goto heap_bad;
  622.                 if ( ((header_32_t *) bh)->flags & MASTER_POINTER_LOCK_MASK )
  623.                     run_type = HEAP_LOCKED_RUN;
  624.                 else if ( ((header_32_t *) bh)->flags & MASTER_POINTER_PURGE_MASK )
  625.                     run_type = HEAP_PURGEABLE_RUN;
  626.                 else
  627.                     run_type = HEAP_UNLOCKED_RUN;
  628.             }
  629.             chunk_size -= heap_scale;
  630.             if ( chunk_size >= heap_scale ) {
  631.                 if ( run_type != last_run_type ) {
  632.                     *p++ = this_run;
  633.                     if ( d->current_heap_transitions == MAX_HEAP_TRANSITIONS )
  634.                         break;
  635.                     ++d->current_heap_transitions;
  636.                     this_run = (int32) run_type << 24;
  637.                     last_run_type = run_type;
  638.                 }
  639.                 i = chunk_size >> heap_scale_2n;
  640.                 this_run += i;
  641.                 chunk_size -= (int32) i << heap_scale_2n;
  642.             }
  643.         }
  644.         else if ( run_type != HEAP_LOCKED_RUN ) {
  645.             if ( block_type == BLOCK_FREE )
  646.                 ;
  647.             else if ( block_type == BLOCK_NON_RELOCATABLE )
  648.                 run_type = HEAP_LOCKED_RUN;
  649.             else {
  650.                 tp = (Ptr) zone + ((header_32_t *) bh)->relative_handle;
  651.                 if ( tp >= BufPtr || ( (int32) tp & 1 ) )
  652.                     goto heap_bad;
  653.                 if ( ((header_32_t *) bh)->flags & MASTER_POINTER_LOCK_MASK )
  654.                     run_type = HEAP_LOCKED_RUN;
  655.                 else if ( ((header_32_t *) bh)->flags & MASTER_POINTER_PURGE_MASK )
  656.                     run_type = HEAP_PURGEABLE_RUN;
  657.                 else
  658.                     run_type = HEAP_UNLOCKED_RUN;
  659.             }
  660.         }
  661.  
  662.         if ( bh + size <= bh )
  663.             goto heap_bad;
  664.         bh += size;
  665.  
  666.         if ( bh < zone->bkLim )
  667.             continue;
  668.  
  669.         if ( bh > zone->bkLim )
  670.             goto heap_bad;
  671.  
  672.         if ( chunk_size )
  673.             ++this_run;
  674.         *p = this_run;
  675.         break;
  676.     }
  677.  
  678.     d->current_heap_ok = TRUE;
  679.     return;
  680.  
  681. heap_bad:
  682.     d->current_heap_ok = FALSE;
  683. }
  684. #endif